#include <cstring>
#include <cerrno>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream>
#include <stdexcept>
#include "Wrappers/UnixUtils/NamedPipe.hpp"

namespace wrappers {
namespace unix_utils {

NamedPipe::NamedPipe(const std::string &fileName) {

  mFileName = fileName;
  if (mkfifo(fileName.c_str(), 0666) == -1
      && errno != EEXIST) {
    throw std::invalid_argument(
	"NamedPipe: The filename `" + fileName
	    + "' could no be used to create a FIFO ("
	    + strerror(errno) + ")");
  }
  OpenFileStream();
}

NamedPipe::NamedPipe(const NamedPipe& from) {
  mFileName = from.mFileName;
  OpenFileStream();
}

NamedPipe::~NamedPipe() {
  mPipeFile.close();
  (void) unlink(mFileName.c_str());
}

NamedPipe& NamedPipe::operator=(const NamedPipe& from) {
  if (this != &from) {
    mPipeFile.close();
    (void) unlink(mFileName.c_str());
    mFileName = from.mFileName;
    OpenFileStream();
  }
  return *this;
}

void NamedPipe::OpenFileStream() {
  mPipeFile.open(mFileName.c_str(),
      std::fstream::in | std::fstream::out | std::fstream::binary);
  if (!mPipeFile.is_open()) {
    unlink(mFileName.c_str());
    throw std::invalid_argument(
	"NamedPipe: The filename `" + mFileName + "' could not be read");
  }
}

/*
std::string NamedPipe::Read() {
  std::string data;

  mPipeFile.flush();
  if (mPipeFile.rdbuf()->in_avail()) {
    std::getline(mPipeFile, data);
  }
  return data;
}

void NamedPipe::Write(const std::string &dataToWrite) {
  mPipeFile << dataToWrite;
  mPipeFile.flush();
}*/

}
}
